package com.shilei.spring.aop.cglib;

import com.shilei.spring.aop.able.Doable;
import com.shilei.spring.aop.aop.Aop;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * 关键代码实现aop
 * @author edz
 */
public class CglibFactory implements MethodInterceptor {
    private Aop aop;
    public Object myCglibCreator(Class clazz, Aop aop) {
        this.aop=aop;
        Enhancer enhancer = new Enhancer();
        //将目标类设置为父类，cglib动态代理增强的原理就是子类增强父类,cglib不能增强目标类为final的类
        //因为final类不能有子类
        enhancer.setSuperclass(clazz);
        //设置回调接口,这里的MethodInterceptor实现类回调接口，而我们又实现了MethodInterceptor,其实
        //这里的回调接口就是本类对象,调用的方法其实就是intercept()方法
        enhancer.setCallback(this);
        //create()方法用于创建cglib动态代理对象
        Object o = enhancer.create();
        return clazz.cast(o);
    }


    /**
     * 回调接口的方法执行的条件是：代理对象执行目标方法时会调用回调接口的方法
     * @param o 被代理的对象
     * @param method 被代理的方法
     * @param objects 方法参数
     * @param methodProxy
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        Object result = aop.around(new Doable() {
            @Override
            public Object done() throws Throwable {
                    return methodProxy.invokeSuper(o, objects);
            }
        },o.getClass(),method,objects);
        return result;
    }

}